home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Frameworks / TransSkel 3.24 / Demos / C Demos / MultiSkel / MSkelHelp.c < prev    next >
Text File  |  1995-03-21  |  8KB  |  317 lines

  1. /*
  2.  * TransSkel multiple-window demonstration: Help module
  3.  * 
  4.  * This module handles a help window, in which text may be scrolled but
  5.  * not edited.  A TextEdit record is used to hold the text, though.
  6.  * 
  7.  * 21 Apr 88 Paul DuBois
  8.  * 29 Jan 89
  9.  * - Conversion for TransSkel 2.0.
  10.  * 12 Jan 91
  11.  * - Conversion for TransSkel 3.0.
  12.  */
  13.  
  14. # include    "TransSkel.h"
  15.  
  16. # include    "MultiSkel.h"
  17.  
  18.  
  19. static TEHandle            teHelp;        /* handle to help window TextEdit record */
  20. static ControlHandle    helpScroll;    /* help window scroll bar */
  21. static short            helpLine;    /* line currently at top of window */
  22. static short            halfPage;    /* number of lines in half a window */
  23.  
  24.  
  25. /*
  26.  * Scroll to the correct position.  lDelta is the
  27.  * amount to CHANGE the current scroll setting by.
  28.  */
  29.  
  30. static void
  31. DoScroll (short lDelta)
  32. {
  33. short    newLine;
  34.  
  35.     newLine = helpLine + lDelta;
  36.     if (newLine < 0)
  37.         newLine = 0;
  38.     if (newLine > GetControlMaximum (helpScroll))
  39.         newLine = GetControlMaximum (helpScroll);
  40.     SetControlValue (helpScroll, newLine);
  41.     lDelta = (helpLine - newLine ) * (**teHelp).lineHeight;
  42.     TEScroll (0, lDelta, teHelp);
  43.     helpLine = newLine;
  44. }
  45.  
  46.  
  47. /*
  48.  * Filter proc for tracking mousedown in scroll bar.  The part code
  49.  * of the part originally hit is stored as the control's reference
  50.  * value.
  51.  *
  52.  * The "void" had better be there!  Otherwise the compiler will treat
  53.  * it as an integer function, not a procedure.
  54.  */
  55.  
  56. static pascal void
  57. TrackScroll (ControlHandle theScroll, short partCode)
  58. {
  59. short            lDelta;
  60.  
  61.     if (partCode == GetControlReference (theScroll))    /* still in same part? */
  62.     {
  63.         switch (partCode)
  64.         {
  65. # if skelUnivHeaders > 1
  66.             case kInUpButtonControlPart: lDelta = -1; break;
  67.             case kInDownButtonControlPart: lDelta = 1; break;
  68.             case kInPageUpControlPart: lDelta = -halfPage; break;
  69.             case kInPageDownControlPart: lDelta = halfPage; break;
  70. # else
  71.             case inUpButton: lDelta = -1; break;
  72.             case inDownButton: lDelta = 1; break;
  73.             case inPageUp: lDelta = -halfPage; break;
  74.             case inPageDown: lDelta = halfPage; break;
  75. # endif
  76.         }
  77.         DoScroll (lDelta);
  78.     }
  79. }
  80.  
  81.  
  82. /* Compatibility machinery for non-universal header compilation */
  83.  
  84. # if !skelUnivHeaders
  85.  
  86. typedef pascal void (*ControlActionProcPtr)(ControlHandle theControl, short partCode);
  87. typedef ControlActionProcPtr ControlActionUPP;
  88.  
  89. # endif
  90.  
  91. /*
  92.  * Set up a variable to point to the scroll tracking procedure.  For 68K code this
  93.  * is just a direct pointer to TrackScroll().  For PowerPC code it is a
  94.  * routine descriptor into which the address of TrackScroll() is stuffed.
  95.  */
  96.  
  97. # if skelPPC        /* PowerPC code */
  98.  
  99. static RoutineDescriptor    trackDesc =
  100.         BUILD_ROUTINE_DESCRIPTOR(uppControlActionProcInfo, TrackScroll);
  101. static ControlActionUPP    trackProc = (ControlActionUPP) &trackDesc;
  102.  
  103. # else                /* 68K code */
  104.  
  105. static ControlActionUPP    trackProc = TrackScroll;
  106.  
  107. # endif
  108.  
  109.  
  110. /*
  111.  * Handle hits in scroll bar
  112.  */
  113.  
  114. static pascal void
  115. Mouse (Point pt, long t, short mods)
  116. {
  117. short    thePart;
  118.  
  119. # if skelUnivHeaders > 1
  120.         if ((thePart = TestControl (helpScroll, pt)) == kInIndicatorControlPart)
  121. # else
  122.         if ((thePart = TestControl (helpScroll, pt)) == inThumb)
  123. # endif
  124.         {
  125.             (void) TrackControl (helpScroll, pt, nil);
  126.             DoScroll (GetControlValue (helpScroll) - helpLine);
  127.         }
  128.         else if (thePart != 0)
  129.         {
  130.             SetControlReference (helpScroll, (long) thePart);
  131.             (void) TrackControl (helpScroll, pt, trackProc);
  132.         }
  133. }
  134.  
  135.  
  136. /*
  137.  * Update help window.  The update event might be in response to a
  138.  * window resizing.  If so, resize the rects and recalc the linestarts
  139.  * of the text.  To resize the rects, only the right edge of the
  140.  * destRect need be changed (the bottom is not used, and the left and
  141.  * top should not be changed). The viewRect should be sized to the
  142.  * screen.  Pull text down if necessary to fill window.
  143.  */
  144.  
  145. static pascal void
  146. Update (Boolean resized)
  147. {
  148. Rect    r;
  149. short    visLines;
  150. short    lHeight;
  151. short    topLines;
  152. short    nLines;
  153. short    scrollLines;
  154.  
  155.     r = helpWind->portRect;
  156.     EraseRect (&r);
  157.     if (resized)
  158.     {
  159.         r.left += 4;
  160.         r.bottom -= 2;
  161.         r.top += 2;
  162.         r.right -= 19;
  163.         (**teHelp).destRect.right = r.right;
  164.         (**teHelp).viewRect = r;
  165.         TECalText (teHelp);
  166.         lHeight = (**teHelp).lineHeight;
  167.         nLines = (**teHelp).nLines;
  168.         visLines = (r.bottom - r.top) / lHeight;
  169.         halfPage = visLines / 2;
  170.         topLines = (r.top - (**teHelp).destRect.top) / lHeight;
  171.         scrollLines = visLines - (nLines - topLines);
  172.         if (scrollLines > 0 && topLines > 0)
  173.         {
  174.             if (scrollLines > topLines)
  175.                 scrollLines = topLines;
  176.             TEScroll (0, scrollLines * lHeight, teHelp);
  177.         }
  178.         scrollLines = nLines - visLines;
  179.         helpLine = (r.top - (**teHelp).destRect.top) / lHeight;
  180.  
  181.         /*
  182.          * Move and resize the scroll bar as well.  The ValidRect call is done
  183.          * because the HideControl adds the control bounds box to the update
  184.          * region - which would generate another update event!  Since everything
  185.          * gets redrawn below, the ValidRect is used to cancel the update.
  186.          */
  187.  
  188.         HideControl (helpScroll);
  189.         r = helpWind->portRect;
  190.         r.left = r.right - 15;
  191.         r.bottom -= 14;
  192.         --r.top;
  193.         ++r.right;
  194.         SizeControl (helpScroll, r.right - r.left, r.bottom - r.top);
  195.         MoveControl (helpScroll, r.left, r.top);
  196.         SetControlMaximum (helpScroll, nLines - visLines < 0 ? 0 : nLines - visLines);
  197.         SetControlValue (helpScroll, helpLine);
  198.         /*if (scrollLines <= 0)
  199.             HiliteControl (helpScroll, (scrollLines > 0 ? 0 : 255));*/
  200.         ShowControl (helpScroll);
  201.         /*if (GetControlValue (helpScroll) > scrollLines)
  202.             DoScroll (GetControlValue (helpScroll) - scrollLines);*/
  203.     }
  204.     DrawGrowBox (helpWind);
  205.     DrawControls (helpWind);    /* redraw scroll bar */
  206.     r = (**teHelp).viewRect;
  207.     TEUpdate (&r, teHelp);        /* redraw text display */
  208.     ValidRect (&helpWind->portRect);
  209. }
  210.  
  211.  
  212. /*
  213.  * When the window comes active, disable the Edit menu and highlight
  214.  * the scroll bar if there are any lines not visible in the content
  215.  * region.  When the window is deactivated, enable the Edit menu and
  216.  * un-highlight the scroll bar.
  217.  */
  218.  
  219. static pascal void
  220. Activate (Boolean active)
  221. {
  222.     DrawGrowBox (helpWind);
  223.     if (active)
  224.     {
  225.         DisableItem (editMenu, 0);
  226.         HiliteControl (helpScroll,
  227.                     (GetControlMaximum (helpScroll) > 0 ? normalHilite : dimHilite));
  228.     }
  229.     else
  230.     {
  231.         EnableItem (editMenu, 0);
  232.         HiliteControl (helpScroll, dimHilite);
  233.     }
  234.     DrawMenuBar ();
  235. }
  236.  
  237.  
  238. static pascal void
  239. Clobber (void)
  240. {
  241.     TEDispose (teHelp);
  242.     DisposeControl (helpScroll);
  243.     DisposeWindow (helpWind);
  244. }
  245.  
  246.  
  247. void
  248. HelpWindInit (void)
  249. {
  250. Rect    r;
  251. Handle    textHandle;
  252. short    visLines;
  253. short    scrollLines;
  254.  
  255.     if (SkelQuery (skelQHasColorQD))
  256.         helpWind = GetNewCWindow (helpWindRes, nil, (WindowPtr) -1L);
  257.     else
  258.         helpWind = GetNewWindow (helpWindRes, nil, (WindowPtr) -1L);
  259.     if (helpWind == (WindowPtr) nil)
  260.         return;
  261.     (void) SkelWindow (helpWind,
  262.                 Mouse,        /* handle clicks in scrollbar */
  263.                 nil,        /* ignore keyclicks */
  264.                 Update,
  265.                 Activate,
  266.                 nil,        /* no close proc */
  267.                 Clobber,    /* disposal proc */
  268.                 nil,        /* no idle proc */
  269.                 false);
  270.  
  271.     TextFont (0);
  272.     TextSize (0);
  273.  
  274.     r = helpWind->portRect;
  275.     r.left += 4;
  276.     r.bottom -= 2;
  277.     r.top += 2;
  278.     r.right -= 19;
  279.     teHelp = TENew (&r, &r);
  280.     textHandle = GetResource ('TEXT', helpTextRes);    /* read help text */
  281.     HLock (textHandle);        /* lock it and insert into TERec */
  282.     TEInsert (*textHandle, GetHandleSize (textHandle), teHelp);
  283.     HUnlock (textHandle);
  284.     ReleaseResource (textHandle);    /* done with it, so goodbye */
  285.     /*
  286.      * Now figure out how many lines will fit in the window and how many
  287.      * will not.  Determine the number of lines in half a window for use
  288.      * in tracking clicks in the page up and page down regions of the
  289.      * scroll bar.  Then create the scroll bar .  Make sure the borders
  290.      * overlap the window frame and the frame of the grow box.
  291.      */
  292.     visLines = (r.bottom - r.top) / (**teHelp).lineHeight;
  293.     scrollLines = (**teHelp).nLines - visLines;
  294.     halfPage = visLines / 2;
  295.     helpLine = 0;
  296.     r = helpWind->portRect;
  297.     r.left = r.right - 15;
  298.     r.bottom -= 14;
  299.     --r.top;
  300.     ++r.right;
  301.     /*
  302.      * Build the scroll bar.  Don't need to bother testing whether to
  303.      * highlight it or not, since that will be done in response to the
  304.      * activate event.
  305.      */
  306.     helpScroll = NewControl (helpWind, &r, "\p", true,
  307.                     helpLine, 0, scrollLines, scrollBarProc, 0L);
  308.  
  309.     /*
  310.      * GetNewWindow generates an update event for entire portRect.
  311.      * Cancel it, since the everything has been drawn already,
  312.      * except for the grow box (which will be drawn in response
  313.      * to the activate event).
  314.      */
  315.     ValidRect (&helpWind->portRect);
  316. }
  317.